package com.szsh.aiot.hsm.thirdService;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.szsh.aiot.framework.config.AbilityParam;
import com.szsh.aiot.hsm.dto.ability.*;
import com.szsh.aiot.hsm.dto.enu.AbilityOperateID;
import com.szsh.aiot.hsm.enums.IdentityType;
import com.szsh.aiot.hsm.utils.RandomUtil;
import org.apache.commons.codec.binary.Base64;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * 能力总线服务
 *
 * @author zhangtt
 */
@Service
public class AbilityClient {
    private static final Logger LOGGER = LoggerFactory.getLogger(AbilityClient.class);
    private final Gson gson = new Gson();

    @Autowired
    private AbilityParam abilityParam;

    @Autowired
    @Qualifier("shorttimeout")
    private RestTemplate restTemplate;

    @Autowired
    @Qualifier("longtimeout")
    private RestTemplate longtimeoutTemplate;



    /**
     * 获取wifi密码
     *
     * @param gateMac
     * @return
     */
    public GetWifiInfoResponse getSSIDInfo(String gateMac) {
        String convertMac = convertMac(gateMac);
        String ssidIndex = "";
        // 获取网关版本
        String version = getGatewayStatus(convertMac);
        LOGGER.info("[{}]版本为：{}", convertMac, version);
        if (version.equals("3.0")) {
            ssidIndex = getSSIDIndexByV3(convertMac);
        } else {
            ssidIndex = getSSIDIndexByV2(convertMac);
        }
        if (StringUtils.isEmpty(ssidIndex)) {
            LOGGER.error("查询ssidIndex失败");
            return null;
        }
        GetWifiInfoResponse response = getWifiInfo(convertMac, ssidIndex);
        if (response == null || StringUtils.isEmpty(response.getStatus())
                || !"0".equals(response.getStatus())) {
            LOGGER.error("SSID信息查询失败！{}", gateMac);
            return null;
        }
        return response;
    }

    /**
     * 3.0网关版本获取ssidIndex：通过SSID_LIST获取所有SSID示例，2.4G使用ssidAlias为2.4G-1的SSID，5G使用ssidAlias为5G-1的SSID
     *
     * @param mac
     *
     * @return ssidIndex
     */
    private String getSSIDIndexByV3(String mac) {
        LOGGER.info("查询3.0网关[{}]所有SSID实例信息..", mac);
        String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.SSID_LIST);
        LOGGER.info("Req: {}", urlTemplate);
        HttpEntity<String> requestEntity = new HttpEntity<>(null, abilityParam.getHttpHeaders());
        // 发送请求
        ResponseEntity<String> respStr = restTemplate.exchange(urlTemplate, HttpMethod.GET, requestEntity, String.class, mac);
        LOGGER.info("Ack:{}", respStr.getBody());
        SSIDListResponse resp = gson.fromJson(respStr.getBody(),SSIDListResponse.class);
        if (resp == null) {
            LOGGER.error("获取SSID示例信息失败。");
            return null;
        }
        List<SSIDList> ssidList = resp.getList();
        String ssidIndex = "";
        for (SSIDList ssid : ssidList) {
            if (ssid.getSsidAlias().equals("2.4G-1")) {
                ssidIndex = ssid.getSsidIndex();
            }
            if (ssid.getSsidAlias().equals("5G-1")) {
                ssidIndex = ssid.getSsidIndex();
                break;
            }
        }
        LOGGER.info("ssidIndex: {}", ssidIndex);
        return ssidIndex;
    }

    /**
     * 1.0/2.0网关版本获取ssidIndex，通过QUERY_SYSTEM_INFO接口判断单频还是双频，单频2.4G默认1，双频5G默认5
     *
     * @param mac
     * @return
     */
    private String getSSIDIndexByV2(String mac) {
        LOGGER.info("1.0/2.0网关[{}]版本查询ssidIndex...", mac);
        String ssidIndex = "";
        String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.QUERY_SYSTEM_INFO);
        LOGGER.info("Req: {}", urlTemplate);
        // 请求数据
        QuerySystemInfoRequestData requestBody = new QuerySystemInfoRequestData();
        requestBody.setCmdType(AbilityOperateID.QUERY_SYSTEM_INFO);
        requestBody.setSequenceId(RandomUtil.randomHexString(8));
        LOGGER.info("ReqBody: {}", gson.toJson(requestBody));
        HttpEntity<String> requestEntity = new HttpEntity<>(gson.toJson(requestBody), abilityParam.getHttpHeaders());
        // 发送请求
        QuerySystemInfoResponse response = restTemplate.postForObject(urlTemplate, requestEntity,
                QuerySystemInfoResponse.class, mac);
        LOGGER.info("Ack: {}", gson.toJson(response));
        if (response == null || !"0".equals(response.getStatus())) {
            LOGGER.info("1.0/2.0网关版本查询ssidIndex失败");
            return null;
        }
        String dualBand = response.getDualBand();
        // 0：单频， 1：双频
        if (dualBand.equals("1")) {
            ssidIndex = "5";
        } else {
            ssidIndex = "1";
        }
        return ssidIndex;
    }

    /**
     * 获取网关版本信息：通过GET_GATEWAY_STATUS接口
     *
     * @param gateMac
     *
     * @return 网关接口返回可能不携带ver字段
     */
    private String getGatewayStatus(String gateMac) {
        LOGGER.info("查询网关[{}]版本信息...", gateMac);
        String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.GET_GATEWAY_STATUS);
        LOGGER.info("Req: {}, mac={}", urlTemplate, gateMac);
        HttpEntity<String> requestEntity = new HttpEntity<>(null, abilityParam.getHttpHeaders());
        // 发送请求
        ResponseEntity<GetGatewayStatusResponse> resp = restTemplate.exchange(urlTemplate,
                HttpMethod.GET, requestEntity, GetGatewayStatusResponse.class, gateMac);
        if (null != resp.getBody()) {
            LOGGER.info("Ack: code [{}], body [{}]", resp.getStatusCode(), gson.toJson(resp.getBody()));
            return resp.getBody().getAppVer();
        }
        return "";
    }


    /**
     * 查询SSID信息
     *
     * @param mac
     * @param ssidIndex
     *
     * @return
     */
    private GetWifiInfoResponse getWifiInfo(String mac, String ssidIndex) {
        LOGGER.info("查询网关[{}]SSID信息..", mac + "-" + ssidIndex);
        String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.GET_WIFI_INFO);
        LOGGER.info("Req: {}", urlTemplate);
        // 请求数据
        GetWifiInfoRequestData requestBody = new GetWifiInfoRequestData();
        requestBody.setCmdType(AbilityOperateID.GET_WIFI_INFO);
        requestBody.setSequenceId(RandomUtil.randomHexString(8));
        requestBody.setSsidIndex(ssidIndex);
        HttpEntity<String> requestEntity = new HttpEntity<>(gson.toJson(requestBody), abilityParam.getHttpHeaders());
        // 发送请求
        GetWifiInfoResponse response = restTemplate.postForObject(urlTemplate, requestEntity,
                GetWifiInfoResponse.class, mac);
        if (response == null) {
            LOGGER.info("Ack: null");
            return null;
        }
        return response;
    }

    /**
     * 设置SSID信息
     *
     * @param mac
     * @param requestBody
     *
     * @return
     */
    public AbilityResponse setSSIDInfo(String mac, SetWifiInfoData requestBody) {
        LOGGER.info("设置用户[{}]WIFI 密码..", mac);
        String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.SET_WIFI_INFO);
        LOGGER.info("Req: {}", urlTemplate);
        // 请求数据
        requestBody.setCmdType(AbilityOperateID.SET_WIFI_INFO);
        requestBody.setSequenceId(RandomUtil.randomHexString(8));
        // 加密方式，默认为3：WPA-PSK
        requestBody.setEncrypt("3");
        // Entity
        HttpEntity<String> requestEntity = new HttpEntity<>(gson.toJson(requestBody), abilityParam.getHttpHeaders());
        // 发送请求
        AbilityResponse response = restTemplate.postForObject(urlTemplate, requestEntity,
                GetWifiInfoResponse.class, convertMac(mac));

        return response;
    }

    /**
     * 插件操作
     *
     * @param gatewayMac
     *            网关mac
     * @param pluginName
     *            插件名称
     * @param pluginVersion
     *            插件版本
     * @param action
     *            0 安装插件 1 卸载插件 2插件启动 3插件停止 4恢复缺省 5查询安装进度 6取消安装
     * @return
     */
    public AbilityResponse pluginOperate(String gatewayMac, String pluginName, String pluginVersion,
            String action) {
        LOGGER.info("执行插件[{}]操作[{}]..", pluginName, action);
        String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.PLUGIN_OPERATION);
        LOGGER.info("Req: {}", urlTemplate);
        // 请求数据
        PluginOperationBody requestBody = new PluginOperationBody();
        // 插件操作
        requestBody.setAction(action);
        requestBody.setPluginName(pluginName);
        requestBody.setVersion(pluginVersion);
        // Entity
        HttpEntity<String> requestEntity = new HttpEntity<>(gson.toJson(requestBody), abilityParam.getHttpHeaders());
        // 发送请求
        AbilityResponse response = restTemplate.postForObject(urlTemplate, requestEntity,
                AbilityResponse.class, convertMac(gatewayMac));

        return response;
    }

    /**
     * 获取已安装插件清单
     *
     * @param gatewayMac
     * @return
     */
    public List<PluginInfo> getPluginList(String gatewayMac) {
        LOGGER.info("[{}]获取已安装插件清单..", gatewayMac);
        String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.LIST_PLUGIN);
        LOGGER.info("Req: {}", urlTemplate);
        // 请求数据
        AbilityRequestData requestBody = new AbilityRequestData();
        requestBody.setCmdType(AbilityOperateID.LIST_PLUGIN);
        requestBody.setSequenceId(RandomUtil.randomHexString(8));
        // Entity
        HttpEntity<String> requestEntity = new HttpEntity<>(gson.toJson(requestBody), abilityParam.getHttpHeaders());
        // 发送请求
        ListPluginResponse response = longtimeoutTemplate.postForObject(urlTemplate, requestEntity,
                ListPluginResponse.class, convertMac(gatewayMac));
        if (response != null && "0".equals(response.getStatus())) {
            return response.getList();
        }
        return new ArrayList<>();
    }

    /**
     * 获取家庭网络拓扑信息
     *
     * @param gateMac
     * @return
     */
    public NetTopologicalInfoResponse getNetTopo(String gateMac) {
        LOGGER.info("获取[{}]家庭网络拓扑信息..", gateMac);
        String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.GET_NET_TOPOLOGICAL_INFO);
        LOGGER.info("Req: {}", urlTemplate);
        // 请求数据
        AbilityRequestData requestBody = new AbilityRequestData();
        requestBody.setCmdType(AbilityOperateID.GET_NET_TOPOLOGICAL_INFO);
        requestBody.setSequenceId(RandomUtil.randomHexString(8));
        // Entity
        HttpEntity<String> requestEntity = new HttpEntity<>(new Gson().toJson(requestBody), abilityParam.getHttpHeaders());
        // 发送请求
        String responseStr = longtimeoutTemplate.postForObject(urlTemplate, requestEntity,
                String.class, convertMac(gateMac));
        LOGGER.info("Ack: {}", responseStr);
        NetTopologicalInfoResponse response = gson.fromJson(responseStr,NetTopologicalInfoResponse.class);
        if (response == null || !"0".equals(response.getStatus())) {
            return response;
        }
        NetTopologicalInfo topologicalInfo = response.getNetTopologicalInfo();
        if (topologicalInfo == null || topologicalInfo.getTopoInfo() == null) {
            return response;
        }
        topologicalInfo.setTopoInfo(getNetTopInfo(topologicalInfo.getTopoInfo()));
        return response;
    }

    public static void main(String[] args) {
        String responseStr = "{\"Result\":0,\"Status\":\"0\",\"NetTopologicalInfo\":{\"Result\":0,\"Status\":0,\"gw_info\":{\"vendor\":\"huawei\",\"2g_channel\":11,\"mac\":\"F84CDA7F9F4A\",\"2g_ssid\":\"lgh\",\"tx_bytes\":36271418,\"rx_bytes\":59779910,\"loid\":\"5715SN122108166\",\"sn\":\"F84CDA-4B862F84CDA7F9F4A\",\"model\":\"Huawei OptiXstar V173\",\"pppoe\":\"057142408545\",\"dns\":\"202.101.172.35\",\"lan_ip\":\"192.168.1.1\",\"wan_ip\":\"183.128.108.120\",\"5g_channel\":36,\"Devname\":\"\",\"5g_ssid\":\"ChinaNet-MeshDA7F9F4A\",\"online_time\":1006995},\"topo_info\":[{\"devname\":\"\",\"mac\":\"1C9E468FA0CC\",\"txbytes\":408602,\"last_inactive_time\":\"2024-05-28 14:04:29\",\"acc_type\":1,\"online_time\":13526,\"dev_type\":\"Pad\",\"model\":\"iPad Mini 2\",\"last_active_time\":\"2024-05-28 14:04:40\",\"hostname\":\"iPad\",\"acc_port\":\"2.4G-1\",\"par_mac\":\"F84CDA7F9F4A\",\"active\":1,\"acc_speed\":13000,\"os\":\"ios\",\"power_level\":-81,\"brand\":\"苹果\",\"rxbytes\":2873816,\"ip\":\"192.168.1.7\"}]},\"devInfo\":{\"gwVer\":\"3.0\",\"2.4G\":[\"1\"],\"5G\":[\"5\",\"16\"]},\"costtime\":5105}\n";
        NetTopologicalInfoResponse response = new Gson().fromJson(responseStr,NetTopologicalInfoResponse.class);
        System.out.println(new Gson().toJson(response));
    }

    /**
     * 拓扑信息处理
     *
     * @param topoInfo
     * @return
     */
    private List<NetTopInfo> getNetTopInfo(Object topoInfo) {
        // 处理topo_info节点，统一返回list
        if (topoInfo instanceof List) {
           return gson.fromJson(gson.toJson(topoInfo),new TypeToken<List<NetTopInfo>>() {}.getType());
          //  return Collections.singletonList(gson.fromJson(gson.toJson(topoInfo), NetTopInfo.class));
        } else {
            List<NetTopInfo> topoList = new ArrayList<>();
            NetTopInfo info = gson.fromJson(gson.toJson(topoInfo),NetTopInfo.class);
            if (null != info) {
                topoList.add(info);
            }
            return topoList;
        }
    }

    /**
     * 获取家庭网络拓扑
     *
     * @param gateMac
     * @return
     */
    public NetTopologicalInfo getTopologicalInfo(String gateMac) {
        try{
            NetTopologicalInfoResponse response = getNetTopo(gateMac);
            if (response == null || !"0".equals(response.getStatus())) {
                return null;
            }
            return response.getNetTopologicalInfo();
        }catch (Exception e){
            LOGGER.error("获取网关mac[{}]的家庭网络拓扑数据出错,",gateMac,e);
        }
        return null;
    }

    /**
     * MAC地址转换，全部大写，无中间分隔符号
     *
     * @param mac
     * @return
     */
    private String convertMac(String mac) {
        if (org.springframework.util.StringUtils.isEmpty(mac)) {
            return null;
        } else if (mac.contains(":")) {
            mac = mac.replace(":", "");
        } else if (mac.contains("-")) {
            mac = mac.replace("-", ":");
        }
        return mac.toUpperCase();
    }

    /**
     * 修改设备名称
     *
     * @param gatewayMac
     *            网关mac
     * @param deviceMac
     *            设备mac
     * @param deviceName
     *            设备名称
     * @return SetAttachDeviceNameResponse
     */
    public HomeNetResponse modifyDevieName(String gatewayMac, String deviceName,
                                           String deviceMac) {
        LOGGER.info("修改网关[{}]下挂设备[{}]别名为[{}]", gatewayMac, deviceMac, deviceName);
        String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.SET_ATTACH_DEVICE_NAME);
        LOGGER.info("Req: {}", urlTemplate);
        SetAttachDeviceNameRequest request = new SetAttachDeviceNameRequest();
        request.setCmdType(AbilityOperateID.SET_ATTACH_DEVICE_NAME);
        request.setMac(deviceMac);
        request.setDeviceName(deviceName);
        request.setSequenceId(RandomUtil.randomHexString(8));
        String thirdReq = gson.toJson(request);
        LOGGER.info("需要修改的设备名称 Req: {}", thirdReq);
        HttpEntity<SetAttachDeviceNameRequest> requestEntity = new HttpEntity<>(request, abilityParam.getHttpHeaders());
        ResponseEntity<HomeNetResponse> resp = restTemplate.exchange(urlTemplate,
                HttpMethod.POST, requestEntity, HomeNetResponse.class, gatewayMac);
        HomeNetResponse response = resp.getBody();
        LOGGER.info("ACK: {}", gson.toJson(response));
        return response;
    }

    /**
     * App详情Client
     *
     * @param requset
     *            AppInfoRequset
     * @return AppDetailInfoResponse
     */
    public AppDetailInfoResponse getAppDetailInfo(AppInfoRequset requset) {
        AppDetailInfoResponse response = new AppDetailInfoResponse();
        try {

            HttpEntity<AppInfoRequset> requestEntity = new HttpEntity<>(requset, abilityParam.getHttpHeaders());
            AbilityRequestData requestBody = new AbilityRequestData();
            requestBody.setSequenceId(RandomUtil.randomHexString(8));
            ResponseEntity<AppDetailInfoResponse> resp = longtimeoutTemplate.exchange(
                    abilityParam.getAppinfoEndpoint(), HttpMethod.POST, requestEntity,
                    AppDetailInfoResponse.class);
            response = resp.getBody();
            return response;
        } catch (Exception e) {
            LOGGER.error("AppDetail Error{}", e.getMessage());
        }
        return response;
    }

    /**
     * 获取禁止上网时间
     *
     * @param gateMac 网关mac
     * @param deviceMac 设备MAC
     * @return GetLanhostTimerResponse
     */
    public GetLanhostTimerResponse getLanhostTime(String gateMac, String deviceMac) {
        GetLanhostTimerResponse response = new GetLanhostTimerResponse();
        try {
            LOGGER.info("获取设备[{}]禁止上网时间..", deviceMac);
            String endpoint = abilityParam.getUrlTemplate(AbilityOperateID.GET_LANHOST_TIMER);
            LOGGER.info("Req: {}", endpoint);
            GetLanhostTimerRequestBody body = new GetLanhostTimerRequestBody();
            body.setDevMac(deviceMac);
            String requestJson = gson.toJson(body);
            LOGGER.info("getLanhostTime Req[{}]", requestJson);
            HttpEntity<String> requestEntity = new HttpEntity<>(requestJson, abilityParam.getHttpHeaders());
            ResponseEntity<GetLanhostTimerResponse> resp = restTemplate.exchange(endpoint,
                    HttpMethod.POST, requestEntity, GetLanhostTimerResponse.class, gateMac);
            if (null == resp || null == resp.getBody()) {
                LOGGER.info("getLanhostTime null");
                return response;
            }
            LOGGER.info("获取下挂设备限时上网响应：{}", resp.getBody());
            return resp.getBody();
        } catch (Exception e) {
            LOGGER.error("getLanhostTime error", e);
        }
        return response;
    }

    /**
     * 设置下挂设备限时上网配置
     *
     * @param gateMac
     *            gateMac
     * @param requestBody
     *            requestBody
     * @return GetLanhostTimerResponse
     */
    public AbilityResponse setLanhostTime(String gateMac, SetLanhostTimeRequestBody requestBody) {
        AbilityResponse response = new AbilityResponse();
        try {
            LOGGER.info("设置下挂设备[{}]禁止上网时间..", gateMac);
            String endpoint = abilityParam.getUrlTemplate(AbilityOperateID.SET_LANHOST_TIMER);
            LOGGER.info("Req: {}", endpoint);
            String requestJson = gson.toJson(requestBody);
            LOGGER.info("setLanhostTime Req[{}]", requestJson);
            HttpEntity<String> requestEntity = new HttpEntity<>(requestJson, abilityParam.getHttpHeaders());
            ResponseEntity<AbilityResponse> resp = restTemplate.exchange(endpoint, HttpMethod.POST,
                    requestEntity, AbilityResponse.class, gateMac);
            if (null == resp || null == resp.getBody()) {
                LOGGER.info("getLanhostTime null");
                return response;
            }
            return resp.getBody();
        } catch (Exception e) {
            LOGGER.error("setLanhostTime error", e);
        }
        return response;
    }

    /**
     * 获取网关下挂终端接入控制黑名单
     *
     * @param gateMac
     * @return GetLanhostTimerResponse
     */
    public GetAttackDeviceRightResponse getAttackDeviceRight(String gateMac) {
        GetAttackDeviceRightResponse response = new GetAttackDeviceRightResponse();
        try {
            LOGGER.info("获取网关下挂终端[{}]接入控制黑名单..", gateMac);
            String endpoint = abilityParam.getUrlTemplate(AbilityOperateID.GET_ATTACH_DEVICE_RIGHT);
            LOGGER.info("Req: {}", endpoint);

            AbilityRequestData body = new AbilityRequestData();
            body.setCmdType(AbilityOperateID.GET_ATTACH_DEVICE_RIGHT);
            body.setSequenceId(RandomUtil.randomHexString(8));
            String requestJson = gson.toJson(body);
            LOGGER.info("getAttackDeviceRight Req[{}]", requestJson);
            HttpEntity<String> requestEntity = new HttpEntity<>(requestJson, abilityParam.getHttpHeaders());
            ResponseEntity<GetAttackDeviceRightResponse> resp = longtimeoutTemplate.exchange(
                    endpoint, HttpMethod.POST, requestEntity, GetAttackDeviceRightResponse.class,
                    gateMac);
            if (null == resp || null == resp.getBody()) {
                LOGGER.info("getAttackDeviceRight null");
                return response;
            }
            return resp.getBody();
        } catch (Exception e) {
            LOGGER.error("getAttackDeviceRight error", e);
        }
        return response;
    }

    /**
     * 2.1订购通知(订购成功,开启业务) 安全业务平台调用该接口通知设备订购了业务,开启业务
     *
     * @param broadbandNO
     *            宽带号
     * @param gatewayMac
     *            用户的网关mac
     * @return 返回结果 0：接口响应成功，业务处理结果 成功； -1：接口响应失败； -2：接口响应成功，业务处理结果 失败；
     *         -3：业务逻辑处理发生异常；
     */
    public String notifyOrderSec(String broadbandNO, String gatewayMac) {
        LOGGER.info("安全业务平台调用该接口通知设备订购了业务，开启业务。broadbandNO[{}],gatewayMac[{}]", broadbandNO,
                gatewayMac);
        String endpoint = abilityParam.getSecendpoint() + "/" + AbilityOperateID.NOTIFY_ORDER_B01_SEC;
        NotifyOrderRequestParam param = new NotifyOrderRequestParam();
        param.setMac(gatewayMac);
        param.setSendPeriod(abilityParam.getNotifyPeriod());
        return notifyOrder(broadbandNO, endpoint, AbilityOperateID.NOTIFY_ORDER_B01_SEC, param);
    }

    /**
     * 2.2 退订通知(退订成功,关闭业务) 安全业务平台调用该接口通知设备退购了业务,关闭业务
     *
     * @param broadbandNO
     *            宽带号
     * @param gatewayMac
     *            用户的网关mac
     * @return 返回结果 0：接口响应成功，业务处理结果 成功； -1：接口响应失败； -2：接口响应成功，业务处理结果 失败；
     *         -3：业务逻辑处理发生异常；
     */
    public String notifyCancelSec(String broadbandNO, String gatewayMac) {
        LOGGER.info("安全业务平台调用该接口通知设备退购了业务,关闭业务。broadbandNO[{}],gatewayMac[{}]", broadbandNO,
                gatewayMac);
        String endpoint = abilityParam.getSecendpoint() + "/" + AbilityOperateID.NOTIFY_CANCEL_B01_SEC;
        NotifyOrderRequestParam param = new NotifyOrderRequestParam();
        param.setMac(gatewayMac);
        return notifyOrder(broadbandNO, endpoint, AbilityOperateID.NOTIFY_CANCEL_B01_SEC, param);
    }

    /**
     * 2.3 安全业务配置查询 安全业务平台调用该接口查询安全业务配置
     *
     * @param broadbandNO
     *            宽带号
     * @param gatewayMac
     *            用户的网关mac
     * @return 返回结果 0：接口响应成功，业务处理结果 成功； -1：接口响应失败； -2：接口响应成功，业务处理结果 失败；
     *         -3：业务逻辑处理发生异常；
     */
    public String querySecConfig(String broadbandNO, String gatewayMac) {
        LOGGER.info("安全业务平台调用该接口查询安全业务配置broadbandNO[{}],gatewayMac[{}]", broadbandNO, gatewayMac);
        String endpoint = abilityParam.getSecendpoint() + "/" + AbilityOperateID.QUERY_B01_SEC_CONFIG;
        NotifyOrderRequestParam param = new NotifyOrderRequestParam();
        param.setMac(gatewayMac);
        return notifyOrder(broadbandNO, endpoint, AbilityOperateID.QUERY_B01_SEC_CONFIG, param);
    }

    /**
     * 2.4安全管家采集订购通知(订购成功,开启业务) 安全业务平台调用该接口通知设备订购了业务,开启安全管家采集业务
     *
     * @param broadbandNO
     *            宽带号
     * @param gatewayMac
     *            用户的网关mac
     * @return 返回结果 0：接口响应成功，业务处理结果 成功； -1：接口响应失败； -2：接口响应成功，业务处理结果 失败；
     *         -3：业务逻辑处理发生异常；
     */
    public String notifyOrderSecCamera(String broadbandNO, String gatewayMac) {
        LOGGER.info("安全业务平台调用该接口通知设备订购了业务,开启安全管家采集业务broadbandNO[{}],gatewayMac[{}]", broadbandNO,
                gatewayMac);
        String endpoint = abilityParam.getSecendpoint() + "/" + AbilityOperateID.NOTIFY_ORDER_B01_SEC_CAMERA;
        NotifyOrderRequestParam param = new NotifyOrderRequestParam();
        param.setMac(gatewayMac);
        param.setLanstatsPeriod(abilityParam.getNotifyPeriod());
        param.setAddr(abilityParam.getNotifyAddr());
        param.setPeriod(abilityParam.getNotifyPeriod());
        return notifyOrder(broadbandNO, endpoint, AbilityOperateID.NOTIFY_ORDER_B01_SEC_CAMERA, param);
    }

    /**
     * 2.5安全管家采集退订通知(退订成功,关闭业务) 安全业务平台调用该接口通知设备退购了业务,关闭安全管家采集业务
     *
     * @param broadbandNO
     *            宽带号
     * @param gatewayMac
     *            用户的网关mac
     * @return 返回结果 0：接口响应成功，业务处理结果 成功； -1：接口响应失败； -2：接口响应成功，业务处理结果 失败；
     *         -3：业务逻辑处理发生异常；
     */
    public String notifyCancelSecCamera(String broadbandNO, String gatewayMac) {
        LOGGER.info("安全业务平台调用该接口通知设备退购了业务,关闭安全管家采集业务broadbandNO[{}],gatewayMac[{}]", broadbandNO,
                gatewayMac);
        String endpoint = abilityParam.getSecendpoint() + "/" + AbilityOperateID.NOTIFY_CANCEL_B01_SEC_CAMERA;
        NotifyOrderRequestParam param = new NotifyOrderRequestParam();
        param.setMac(gatewayMac);
        return notifyOrder(broadbandNO, endpoint, AbilityOperateID.NOTIFY_CANCEL_B01_SEC_CAMERA, param);
    }

    /**
     * 2.6安全管家采集配置查询 安全业务平台调用该接口查询安全管家采集业务配置
     *
     * @param broadbandNO
     *            宽带号
     * @param gatewayMac
     *            用户的网关mac
     * @return 返回结果 0：接口响应成功，业务处理结果 成功； -1：接口响应失败； -2：接口响应成功，业务处理结果 失败；
     *         -3：业务逻辑处理发生异常；
     */
    public String queryCameraConfig(String broadbandNO, String gatewayMac) {
        LOGGER.info("安全业务平台调用该接口查询安全管家采集业务配置broadbandNO[{}],gatewayMac[{}]", broadbandNO,
                gatewayMac);
        String endpoint = abilityParam.getSecendpoint() + "/" + AbilityOperateID.QUERY_B01_SEC_CAMERA_CONFIG;
        NotifyOrderRequestParam param = new NotifyOrderRequestParam();
        param.setMac(gatewayMac);
        return notifyOrder(broadbandNO, endpoint, AbilityOperateID.QUERY_B01_SEC_CAMERA_CONFIG, param);
    }

    /**
     * 2.7 日报上报业务订购通知 安全业务平台调用该接口通知日报上报业务平台订购业务
     *
     * @param broadbandNO
     *            宽带号
     * @param maclist
     *            用户的网关mac集合，没有冒号
     * @return 返回结果 0：接口响应成功，业务处理结果 成功； -1：接口响应失败； -2：接口响应成功，业务处理结果 失败；
     *         -3：业务逻辑处理发生异常；
     */
    public String notifyOrderVprovset(String broadbandNO, List<String> maclist) {
        LOGGER.info("安全业务平台调用该接口通知日报上报业务平台订购业务broadbandNO[{}],gatewayMac[{}]", broadbandNO,
                maclist);
        String endpoint = abilityParam.getSecendpoint() + "/" + AbilityOperateID.NOTIFY_ORDER_VPROVSET;
        NotifyOrderRequestParam param = new NotifyOrderRequestParam();
        param.setName(abilityParam.getAreaName());
        param.setMaclist(maclist);
        return notifyQuery(broadbandNO, endpoint, AbilityOperateID.NOTIFY_ORDER_VPROVSET, param);
    }

    /**
     * 2.8 日报上报业务退订通知 安全业务平台调用该接口通知日报上报业务平台退购了业务
     *
     * @param broadbandNO
     *            宽带号
     * @param maclist
     *            用户的网关mac集合，没有冒号
     * @return 返回结果 0：接口响应成功，业务处理结果 成功； -1：接口响应失败； -2：接口响应成功，业务处理结果 失败；
     *         -3：业务逻辑处理发生异常；
     */
    public String notifyCancelVprovset(String broadbandNO, List<String> maclist) {
        LOGGER.info("安全业务平台调用该接口通知日报上报业务平台退购了业务broadbandNO[{}],gatewayMac[{}]", broadbandNO,
                maclist);
        String endpoint = abilityParam.getSecendpoint() + "/" + AbilityOperateID.NOTIFY_CANCEL_VPROVSET;
        NotifyOrderRequestParam param = new NotifyOrderRequestParam();
        param.setName(abilityParam.getAreaName());
        param.setMaclist(maclist);
        return notifyQuery(broadbandNO, endpoint, AbilityOperateID.NOTIFY_CANCEL_VPROVSET, param);
    }

    /**
     * 2.9 日报上报业务配置查询 安全业务平台调用该接口查询日报上报业务配置
     *
     * @param broadbandNO
     *            宽带号
     * @param maclist
     *            用户的网关mac集合，没有冒号
     * @return 返回结果 0：接口响应成功，业务处理结果 成功； -1：接口响应失败； -2：接口响应成功，业务处理结果 失败；
     *         -3：业务逻辑处理发生异常；
     */
    public String queryVprovsetConfig(String broadbandNO, List<String> maclist) {
        LOGGER.info("安全业务平台调用该接口查询安全管家采集业务配置broadbandNO[{}],gatewayMac[{}]", broadbandNO, maclist);
        String endpoint = abilityParam.getSecendpoint() + "/" + AbilityOperateID.QUERY_VPROVSET_CONFIG;
        NotifyOrderRequestParam param = new NotifyOrderRequestParam();
        param.setName(abilityParam.getAreaName());
        param.setMaclist(maclist);
        return notifyQuery(broadbandNO, endpoint, AbilityOperateID.QUERY_VPROVSET_CONFIG, param);
    }

    /**
     * 处理 2.1~2.6 6个业务接口返回
     *
     * @param endpoint
     * @param operateID
     * @param reqParam
     *            返回结果 0：接口响应成功，业务处理成功； -1：接口响应失败； -2：接口响应成功，但是业务处理结果是失败；
     *            -3：业务逻辑处理发生异常；
     * @return
     */
    private String notifyOrder(String broadbandNO, String endpoint, String operateID, NotifyOrderRequestParam reqParam) {
        NotifyOrderRequest request = abilityParam.getRequestBody();
        try {
            NotifyOrderResponse response = dealNotifyResponse(request, endpoint, operateID, reqParam);
            if (response == null || response.getResultCode() != 0) {
                String result = "接口返回失败";
                if (response != null) {
                    result = response.getResultInfo();
                }
                LOGGER.info("[{}]调用设备增值平台B01业务同步接口失败，流水号：{},返回结果：{}", broadbandNO,
                        request.getTransactionid(), result);
                return "-1" + "|" + result;
            }
            NotifyOrderResponseParam responseParam = response.getParam();
            if (responseParam == null || responseParam.getStatus() != 0) {
                LOGGER.info("[{}]调用设备增值平台B01业务同步接口成功，业务处理结果失败，流水号：{},返回结果：{}", broadbandNO,
                        request.getTransactionid(), response.getResultInfo());
                return "-2" + "|" + response.getResultInfo();
            }
            LOGGER.info("[{}]调用设备增值平台B01业务同步接口成功，业务处理结果成功，流水号：{},返回结果：{}", broadbandNO,
                    request.getTransactionid(), response.getResultInfo());
            return responseParam.getStatus() + "|" + response.getResultInfo();
        } catch (Exception e) {
            LOGGER.error("流水号：{},[{}]增值平台B01业务接口发生异常", request.getTransactionid(), broadbandNO, e);
            return "-3" + "|" + e.getMessage();
        }
    }

    /**
     * 处理 2.7~2.9 3个业务接口返回
     *
     * @param endpoint
     * @param operateID
     * @param reqParam
     *            返回结果 0：接口响应成功，业务处理结果 成功； -1：接口响应失败； -2：接口响应成功，业务处理结果 失败；
     *            -3：业务逻辑处理发生异常；
     * @return
     */
    private String notifyQuery(String broadbandNO, String endpoint, String operateID,
            NotifyOrderRequestParam reqParam) {
        NotifyOrderRequest request = abilityParam.getRequestBody();
        try {
            NotifyOrderResponse response = dealNotifyResponse(request, endpoint, operateID, reqParam);
            if (response == null || response.getResultCode() != 0) {
                String result = "接口返回失败";
                if (response != null) {
                    result = response.getResultInfo();
                }
                LOGGER.info("[{}]调用设备增值平台B01业务同步接口失败，流水号：{},返回结果：{}", broadbandNO,
                        request.getTransactionid(), result);
                return "-1" + "|" + result;
            }
            NotifyOrderResponseParam responseParam = response.getParam();
            if (responseParam == null || responseParam.getCode() != 0) {
                LOGGER.info("[{}]调用设备增值平台B01业务同步接口成功，业务处理结果是失败，流水号：{},返回结果：{}", broadbandNO,
                        request.getTransactionid(), response.getResultInfo());
                return "-2" + "|" + response.getResultInfo();
            }
            LOGGER.info("[{}]调用设备增值平台B01业务同步接口成功，业务处理结果成功，流水号：{},返回结果：{}", broadbandNO,
                    request.getTransactionid(), response.getResultInfo());
            return responseParam.getCode() + "|" + response.getResultInfo();
        } catch (Exception e) {
            LOGGER.error("流水号：{},[{}]增值平台B01业务接口发生异常", request.getTransactionid(), broadbandNO, e);
            return "-3" + "|" + e.getMessage();
        }
    }

    /**
     * 处理请求的公共部分
     *
     * @param request
     * @param endpoint
     * @param operateID
     * @param reqParam
     * @return
     * @throws Exception
     */
    private NotifyOrderResponse dealNotifyResponse(NotifyOrderRequest request, String endpoint,
            String operateID, NotifyOrderRequestParam reqParam) {
        // 请求数据
        request.setParam(reqParam);
        LOGGER.info("b01ServiceReqUrl:{}", endpoint);
        HttpEntity<String> requestEntity = new HttpEntity<>(gson.toJson(request),
                abilityParam.getHttpHeaders());
        String respContent = longtimeoutTemplate.postForObject(endpoint, requestEntity,
                String.class, operateID);
        LOGGER.info("b01ServiceResp:{}", respContent);
        return gson.fromJson(respContent,NotifyOrderResponse.class);
    }

    /**
     * 家庭网络可视化拓扑(带离线设备信息) 和获取家庭网络拓扑接口入参和返回相同， oprtateID 不同
     *
     */
    public NetTopologicalInfoResponse getAllTopoinfo(String gateMac) {
        
        try {
            LOGGER.info("获取[{}]家庭网络可视化拓扑(带离线设备信息)", gateMac);
            String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.GET_ALL_TOPOINFO);
            // 请求数据
            LOGGER.info("Req: {}", urlTemplate);
            AbilityRequestData body = new AbilityRequestData();
            body.setCmdType(AbilityOperateID.GET_ALL_TOPOINFO);
            body.setSequenceId(RandomUtil.randomHexString(8));
            
            // Entity
            HttpEntity<String> requestEntity = new HttpEntity<>(gson.toJson(body), abilityParam.getHttpHeaders());
            // 发送请求
            ResponseEntity<String> resp = longtimeoutTemplate.exchange(urlTemplate, HttpMethod.POST,
                    requestEntity, String.class, gateMac);
            String thirdResult = resp.getBody();
            LOGGER.info("获取[{}]家庭网络可视化拓扑(带离线设备信息)Rsp：{}", gateMac, thirdResult);
            return gson.fromJson(thirdResult,NetTopologicalInfoResponse.class);
        } catch (Exception e) {
            LOGGER.error("获取[{}]家庭网络可视化拓扑(带离线设备信息)出错", gateMac, e);
        }
        return new NetTopologicalInfoResponse();
    }

    /**
     * 网关下挂终端接入控制 一键断网或者一键恢复联网
     *
     * @param gateMac
     *            gateaMac
     * @param deviceMac
     *            deviceMac
     * @param devicename
     *            设备名称
     * @param internetTask
     *            需要操作的命令 OFF 拉黑；ON:恢复联网;
     * @return
     */
    public AbilityResponse setAttachDeviceRight(String gateMac, String deviceMac, String devicename,
            String internetTask, String storageTask) {
        AbilityResponse rspBody = null;
        try {
            AttachDeviceReqBody body = new AttachDeviceReqBody();
            body.setCmdType(AbilityOperateID.SET_ATTACH_DEVICE_RIGHT);
            body.setDevName(devicename);
            body.setMac(deviceMac);
            body.setInternetAccessRight(internetTask);
            body.setStorageAccessRight(storageTask);
            body.setSequenceId(RandomUtil.randomHexString(8));
            String requestJson = gson.toJson(body);
            LOGGER.info("AttachDeviceRightClient Req[{}]", requestJson);
            HttpEntity<String> requestEntity = new HttpEntity<>(requestJson, abilityParam.getHttpHeaders());
            String rspStr = restTemplate.postForObject(
                    abilityParam.getUrlTemplate(AbilityOperateID.SET_ATTACH_DEVICE_RIGHT),
                    requestEntity, String.class, gateMac);
            LOGGER.info("AttachDeviceRightClient Rsp[{}]", rspStr);
            return gson.fromJson(rspStr,AbilityResponse.class);
        } catch (Exception e) {
            LOGGER.error("调用网关下挂终端接入控制接口异常", e);
        }
        return rspBody;
    }

    /**
     * 查询e-Link路由器型号、MAC、硬件版本
     * @param mac 路由器mac
     *
     */
    public GetApInfo getApInfo(String mac) {
        try {
            LOGGER.info("查询e-Link路由器[{}]的信息..", mac);
            String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.GET_AP_INFO);
            LOGGER.info("Req: {}", urlTemplate);
            HttpEntity<String> requestEntity = new HttpEntity<>(null, abilityParam.getHttpHeaders());
            // 发送请求
            ResponseEntity<String> respStr = restTemplate.exchange(urlTemplate, HttpMethod.GET,
                    requestEntity, String.class, mac);
            LOGGER.info("Ack:{}", respStr.getBody());
            GetApInfoResp resp = gson.fromJson(respStr.getBody(),GetApInfoResp.class);
            if (resp == null) {
                LOGGER.error("查询e-Link路由器[{}]的信息失败。",mac);
                return null;
            }
            String paramStr = resp.getParamStr();
            if(StringUtils.isEmpty(paramStr)){
                LOGGER.error("查询e-Link路由器[{}]的信息失败,返回的信息为空",mac);
                return null;
            }
            String plainText = new String(Base64.decodeBase64(paramStr));
            LOGGER.info("查询e-Link路由器[{}]的信息[{}]",mac,plainText);
            return gson.fromJson(plainText,GetApInfo.class);
        } catch (Exception e) {
            LOGGER.error("查询e-Link路由器[{}]的信息出错,", mac, e);
        }
        return null;
    }

    /**
     * 获取路由器插件列表
     * @param mac 路由器mac
     *
     */
    public List<ApPlugin> getApPluginList(String mac) {
        List<ApPlugin> apPlugins = null;
        try {
            LOGGER.info("查询[{}]路由器插件列表..", mac);
            String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.AP_LIST_PLUGIN);
            LOGGER.info("Req: {}", urlTemplate);
            HttpEntity<String> requestEntity = new HttpEntity<>(null, abilityParam.getHttpHeaders());
            // 发送请求
            ResponseEntity<String> respStr = restTemplate.exchange(urlTemplate, HttpMethod.GET,
                    requestEntity, String.class, mac);
            LOGGER.info("Ack:{}", respStr.getBody());
            ApPluginListResp resp = gson.fromJson(respStr.getBody(),ApPluginListResp.class);
            if (resp == null) {
                LOGGER.error("查询[{}]路由器插件列表失败。",mac);
                return apPlugins;
            }
            apPlugins = resp.getApPlugins();
            if(CollectionUtils.isEmpty(apPlugins)){
                LOGGER.error("查询[{}]路由器插件列表失败,返回的信息为空",mac);
                return apPlugins;
            }
            LOGGER.info("查询[{}]路由器插件列表{}",mac,gson.toJson(apPlugins));
            return apPlugins;
        } catch (Exception e) {
            LOGGER.error("查询[{}]路由器插件列表出错,", mac, e);
        }
        return apPlugins;
    }

    /**
     * 修改路由器的工作模式
     *
     * @param gatewayMac 网关mac
     * @param deviceMac 设备mac
     * @param apPlugin 插件
     * @param workMode 工作模式
     * @return ApPluginConfigResp
     */
    public ApPluginConfigResp apPluginConfig(String gatewayMac, String deviceMac, ApPlugin apPlugin, String workMode) {
        try{
            LOGGER.info("修改网关[{}]下挂路由器[{}]的工作模式为[{}]", gatewayMac, deviceMac, workMode);
            String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.AP_PLUGIN_CONFIG);
            LOGGER.info("Req: {}", urlTemplate);
            ApPluginConfigReq apPluginConfigReq = getApPluginConfigReq(gatewayMac,workMode,apPlugin);
            String thirdReq =gson.toJson(apPluginConfigReq);
            LOGGER.info("修改路由器[{}]的工作模式 Req: {}", deviceMac,thirdReq);
            HttpEntity<ApPluginConfigReq> requestEntity = new HttpEntity<>(apPluginConfigReq,
                    abilityParam.getHttpHeaders());
            ResponseEntity<ApPluginConfigResp> resp = restTemplate.exchange(urlTemplate,
                    HttpMethod.POST, requestEntity, ApPluginConfigResp.class, deviceMac);
            ApPluginConfigResp response = resp.getBody();
            LOGGER.info("ACK: {}",gson.toJson(response));
            return response;
        }catch (Exception e){
            LOGGER.error("修改路由器[{}]的工作模式出错,",deviceMac,e);
        }
        return null;
    }

    private ApPluginConfigReq getApPluginConfigReq(String gatewayMac,String workMode,ApPlugin apPlugin){
        ApPluginConfigReq apPluginConfigReq = new ApPluginConfigReq();
        apPluginConfigReq.setPluginname(apPlugin.getPluginname());
        apPluginConfigReq.setVersion(apPlugin.getVersion());
        ApPluginConfigReqParam parameter = new ApPluginConfigReqParam();
        parameter.setType("ubus_call");
        parameter.setSequence(new SecureRandom().nextInt(10000));
        parameter.setMac(gatewayMac);
        ApPluginConfigReqBody data = new ApPluginConfigReqBody();
        data.setObject("ctcapd.devinfo");
        data.setMethod("set");
        ApPluginConfigReqMessage message = new ApPluginConfigReqMessage();
        message.setWorkmode(workMode);
        data.setMessage(message);
        List<ApPluginConfigReqBody> datas = new ArrayList<>();
        datas.add(data);
        parameter.setData(datas);
        apPluginConfigReq.setParameter(parameter);
        return apPluginConfigReq;
    }

    /**
     * 设置网关阻断app
     *
     * @param appids
     * @param broadbandNO
     * @param gateMac
     * @return
     */
    public AbilityResponse setAppBlock(String appids, String broadbandNO, String gateMac) {
        try {
            LOGGER.info("执行用户[{}]网关[{}]的app阻断操作..", broadbandNO, gateMac);
            String urlTemplate = abilityParam.getUrlTemplate(AbilityOperateID.APPLICATION_INTERCEPT);
            LOGGER.info("执行用户[{}]网关[{}]的app阻断操作 Req: {}", broadbandNO, gateMac, urlTemplate);
            // 请求数据
            SetBlockReq requestBody = new SetBlockReq();
            requestBody.setCmdType(AbilityOperateID.SET_DROP_CMD);
            requestBody.setSequenceId(RandomUtil.randomHexString(8));
            List<SetBlockInfo> info = new ArrayList<>();
            SetBlockInfo setBlockInfo = new SetBlockInfo();
            String[] appidArr = appids.split(",");
            setBlockInfo.setFobAppList(appidArr);
            info.add(setBlockInfo);
            requestBody.setInfo(info);
            // Entity
            HttpEntity<String> requestEntity = new HttpEntity<>(gson.toJson(requestBody),
                    abilityParam.getHttpHeaders());
            // 发送请求
            AbilityResponse response = restTemplate.postForObject(urlTemplate, requestEntity,
                    AbilityResponse.class, convertMac(gateMac));
            LOGGER.info("执行用户[{}]网关[{}]的app阻断操作 Rsp[{}]", broadbandNO, gateMac, gson.toJson(response));
            return response;
        } catch (Exception e) {
            LOGGER.error("执行用户[{}]网关[{}]的app阻断操作出错,", broadbandNO, gateMac, e);
        }
        return new AbilityResponse();
    }

    /**
     * 是否已安装目标插件
     *
     * @param gatewayMac
     * @param pluginName
     * @param pluginVersion
     * @return
     */
    public boolean isInstall(String gatewayMac, String pluginName, String pluginVersion,
                             int identity) {
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("gatewayMac:[{}],pluginName:[{}],pluginVersion:[{}],identity:[{}]",
                    gatewayMac, pluginName, pluginVersion, identity);
        }
        // 获取插件列表
        List<PluginInfo> pluginList;
        try {
            pluginList = getPluginList(gatewayMac);
        } catch (Exception e) {
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error("根据网关MAC{}调用获取插件列表接口超时", gatewayMac, e);
            }
            return false;
        }
        if (CollectionUtils.isEmpty(pluginList)) {
            if (LOGGER.isWarnEnabled()) {
                LOGGER.warn("用户插件信息不存在");
            }
            return false;
        }
        for (PluginInfo plugin : pluginList) {
            if (Objects.equals(plugin.getPluginName(), pluginName)) {
                // 是需要比对的插件
                if ((identity == IdentityType.MAIKE.getType()
                        && StringUtils.isNotBlank(plugin.getVersion())
                        && getLastVer(plugin.getVersion()) >= 36)
                        || plugin.getVersion().equals(pluginVersion)) {
                    // 迈科插件判断，如果网关插件列表中存在version最后两位 >=36 ，则认为已安装B01插件

                    // 库里面版本 <= 网关版本 : true
                    // 库里面版本 > 网关版本 : false
                    return getLastVer(pluginVersion) <= getLastVer(plugin.getVersion());
                }
            }
        }
        return false;
    }

    /**
     * 返回版本号码的最后一段小版本号
     * @return
     */
    public static int getLastVer(String version) {
        String[] verArr = version.split("\\.");
        return Integer.parseInt(verArr[verArr.length - 1]);
    }

}
